﻿using MySql.Data.MySqlClient;

using MySqlX.XDevAPI.Common;
using NewChillers.Helpers;
using NewChillers.Models;
using NewChillers.Models.Events;
using NewChillers.Utils;
using NewChillers.Views;
using SharpVectors.Dom.Events;

using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;
using static NewChillers.ViewModels.ShellViewModel;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace NewChillers.ViewModels
{
    public class HomeViewModel : ObservableObject
    {
        #region 枚举
        public enum DeviceRunningState // 状态指示灯
        {
            RunState,   // 运行状态（对应绿色）
            TipState,   // 提示/报警状态（对应红色闪烁）
            StopState   // 停止状态（对应灰色）
        }
        public enum ProcessStep // 步骤指示器
        {
            Pending,        // 等待启动
            Vacuum,         // 真空步骤
            VacuumHold,     // 真空保持步骤
            Helium,         // 充氦步骤
            HeliumHold,     // 充氦保持步骤
            FinalHelium,    // 最后稳压步骤
            FinalHeliumHold // 最后稳压保持步骤
        }
        #endregion

        #region 属性
        private UserModel _currentUser;
        private ProductModel _productModel;
        private readonly ShellViewModel _shellViewModel;
        private CancellationTokenSource _cts; // 取消令牌源（用于停止流程）
        private DispatcherTimer _processTimer; //总时长计时器
        private TimeSpan _elapsedTime; //工作流程所用时间

        //private bool _isCheckedProduct01;
        //private bool _isCheckedProduct02;
        //private bool _isCheckedProduct03;
        //private bool _isCheckedProduct04;
        //private bool _isCheckedProduct05;
        //private bool _isCheckedProduct06;

        // 流程1参数
        private int _cycleCount_01; // 流程一循环次数
        private double _vacuumValue_01; // 流程一真空度
        private int _vacuumHoldTime_01; // 流程一真空保持时间
        private double _heliumValue_01; // 流程一充氦气值
        private int _heliumHoldTime_01; // 流程一充氦气保持时间
        private double _finalHeliumValue_01; // 流程一最后充氦气值
        private int _finalHoldTime_01; // 流程一最后保压时间

        // 流程2参数
        private int _cycleCount_02; // 流程二循环次数
        private double _vacuumValue_02; // 流程二真空度
        private int _vacuumHoldTime_02; // 流程二真空保持时间
        private double _heliumValue_02; // 流程二充氦气值
        private int _heliumHoldTime_02; // 流程二充氦气保持时间
        private double _finalHeliumValue_02; // 流程二最后充氦气值
        private int _finalHoldTime_02; // 流程二最后保压时间

        //进度条
        //流程一
        private double _cycleCountBarValue_01;//循环次数进度条_01
        private double _vacuumBarValue_01; // 抽真空进度条_01
        private double _vacuumHoldTimeBarValue_01; // 抽真空保持时间进度条_01
        private double _heliumBarValue_01;//充氦气进度条_01
        private double _heliumHoldTimeBarValue_01;//充氦气保持时间进度条_01
        private double _finalHeliumBarValue_01;//充氦气最后进度条_01
        private double _finalHoldTimeBarValue_01;//充氦气最后保持时间进度条_01

        //流程二
        private double _cycleCountBarValue_02;
        private double _vacuumBarValue_02;
        private double _vacuumHoldTimeBarValue_02;
        private double _heliumBarValue_02;
        private double _heliumHoldTimeBarValue_02;
        private double _finalHeliumBarValue_02;
        private double _finalHoldTimeBarValue_02;

        // 实时值 非进度条
        //流程一
        private int _cycleCountRealTime_01; // 当前循环_01
        private double _vacuumRealTime_01; // 当前真空度_01
        private int _vacuumTimeRealTime_01; // 当前真空保持时间_01
        private double _heliumRealTime_01; // 当前充氦压力_01
        private int _heliumTimeRealTime_01; // 当前充氦保持时间_01
        private double _finalHeliumRealTime_01; // 当前稳压压力_01
        private int _finalHeliumTimeRealTime_01; // 当前稳压保持时间_01

        //流程二
        private int _cycleCountRealTime_02; // 当前循环_02
        private double _vacuumRealTime_02; // 当前真空度_02
        private int _vacuumTimeRealTime_02; // 当前真空保持时间_02
        private double _heliumRealTime_02; // 当前充氦压力_02
        private int _heliumTimeRealTime_02; // 当前充氦保持时间_02
        private double _finalHeliumRealTime_02; // 当前稳压压力_02
        private int _finalHeliumTimeRealTime_02; // 当前稳压保持时间_02

        #region 倒计时 不同呈现情况 备份 1、带小数的倒计时 2、整数倒计时 3、00:00:00倒计时
        // 计算属性 倒计时 保留1位小数的计算不能省 直接计算(int)20 - (double)15.7 = 4.300000000000001 or 4.299999999999999 离谱
        // AwayFromZero 四舍五入 或许整数更好？
        //public double VacuumHoldTimeCountdown_01 => Math.Round(VacuumHoldTime_01 - VacuumTimeRealTime_01, 1, MidpointRounding.AwayFromZero); // 真空保持倒计时
        //public double HeliumHoldTimeCountdown_01 => Math.Round(HeliumHoldTime_01 - HeliumTimeRealTime_01, 1, MidpointRounding.AwayFromZero); // 充氦保持倒计时
        //public double FinalHoldTimeCountdown_01 => Math.Round(FinalHoldTime_01 - FinalHeliumTimeRealTime_01, 1, MidpointRounding.AwayFromZero); // 稳压倒计时
        //public double VacuumHoldTimeCountdown_02 => Math.Round(VacuumHoldTime_02 - VacuumTimeRealTime_02, 1, MidpointRounding.AwayFromZero); // 真空保持倒计时
        //public double HeliumHoldTimeCountdown_02 => Math.Round(HeliumHoldTime_02 - HeliumTimeRealTime_02, 1, MidpointRounding.AwayFromZero); // 充氦保持倒计时
        //public double FinalHoldTimeCountdown_02 => Math.Round(FinalHoldTime_02 - FinalHeliumTimeRealTime_02, 1, MidpointRounding.AwayFromZero); // 稳压倒计时

        //public int VacuumHoldTimeCountdown_01 => VacuumHoldTime_01 - VacuumTimeRealTime_01; // 真空保持倒计时
        //public int HeliumHoldTimeCountdown_01 => HeliumHoldTime_01 - HeliumTimeRealTime_01; // 充氦保持倒计时
        //public int FinalHoldTimeCountdown_01 => FinalHoldTime_01 - FinalHeliumTimeRealTime_01; // 稳压倒计时
        //public int VacuumHoldTimeCountdown_02 => VacuumHoldTime_02 - VacuumTimeRealTime_02; // 真空保持倒计时
        //public int HeliumHoldTimeCountdown_02 => HeliumHoldTime_02 - HeliumTimeRealTime_02; // 充氦保持倒计时
        //public int FinalHoldTimeCountdown_02 => FinalHoldTime_02 - FinalHeliumTimeRealTime_02; // 稳压倒计时
        #endregion

        public TimeSpan VacuumHoldTimeCountdown_01 => TimeSpan.FromSeconds(VacuumHoldTime_01 - VacuumTimeRealTime_01); // 真空保持倒计时
        public TimeSpan HeliumHoldTimeCountdown_01 => TimeSpan.FromSeconds(HeliumHoldTime_01 - HeliumTimeRealTime_01); // 充氦保持倒计时
        public TimeSpan FinalHoldTimeCountdown_01 => TimeSpan.FromSeconds(FinalHoldTime_01 - FinalHeliumTimeRealTime_01); // 稳压倒计时
        public TimeSpan VacuumHoldTimeCountdown_02 => TimeSpan.FromSeconds(VacuumHoldTime_02 - VacuumTimeRealTime_02); // 真空保持倒计时
        public TimeSpan HeliumHoldTimeCountdown_02 => TimeSpan.FromSeconds(HeliumHoldTime_02 - HeliumTimeRealTime_02); // 充氦保持倒计时
        public TimeSpan FinalHoldTimeCountdown_02 => TimeSpan.FromSeconds(FinalHoldTime_02 - FinalHeliumTimeRealTime_02); // 稳压倒计时

        private DeviceRunningState _currentState;

        //文本输入框是否可用
        private bool _cycleCount01IsEnabled;
        private bool _vacuumValue01IsEnabled;
        private bool _vacuumHoldTime01IsEnabled;
        private bool _heliumValue01IsEnabled;
        private bool _heliumHoldTime01IsEnabled;
        private bool _finalHeliumValue01IsEnabled;
        private bool _finalHoldTime01IsEnabled;

        private bool _cycleCount02IsEnabled;
        private bool _vacuumValue02IsEnabled;
        private bool _vacuumHoldTime02IsEnabled;
        private bool _heliumValue02IsEnabled;
        private bool _heliumHoldTime02IsEnabled;
        private bool _finalHeliumValue02IsEnabled;
        private bool _finalHoldTime02IsEnabled;

        //流程按钮
        private bool _process1IsEnabled;
        private bool _process2IsEnabled;

        //启动按钮
        private bool _startWork1IsEnabled;
        private bool _startWork2IsEnabled;

        //停止按钮
        private bool _stop1IsEnabled;
        private bool _stop2IsEnabled;

        //选择配方按钮
        private bool _selectRecipeBtnIsEnabled_01;
        private bool _selectRecipeBtnIsEnabled_02;


        //漏率检测
        private string _deviceLeakageRate = "0.0";
        private string _productLeakageRate = "0.0";
        private bool _isDeviceLeakageTesting = false;
        private bool _isProductLeakageTesting = false;
        private string _deviceLeakageTestContent = "设备漏率自检";
        private string _productLeakageTestContent = "产品漏率检测";

        public string DeviceLeakageRate
        {
            get { return _deviceLeakageRate; }
            set
            {
                _deviceLeakageRate = value;
                RaisePropertyChanged();
            }
        }

        public string ProductLeakageRate
        {
            get { return _productLeakageRate; }
            set
            {
                _productLeakageRate = value;
                RaisePropertyChanged();
            }
        }

        public bool IsDeviceLeakageTesting
        {
            get { return _isDeviceLeakageTesting; }
            set
            {
                _isDeviceLeakageTesting = value;
                RaisePropertyChanged();
                // 当设备漏率检测状态改变时，更新产品漏率检测的可用性
                RaisePropertyChanged(nameof(IsProductLeakageTestingEnabled));
            }
        }

        public bool IsProductLeakageTesting
        {
            get { return _isProductLeakageTesting; }
            set
            {
                _isProductLeakageTesting = value;
                RaisePropertyChanged();
                // 当产品漏率检测状态改变时，更新设备漏率检测的可用性
                RaisePropertyChanged(nameof(IsDeviceLeakageTestingEnabled));
            }
        }

        public bool IsProductLeakageTestingEnabled => !IsDeviceLeakageTesting;
        public bool IsDeviceLeakageTestingEnabled => !IsProductLeakageTesting;


        public string DeviceLeakageTestContent
        {
            get { return _deviceLeakageTestContent; }
            set
            {
                _deviceLeakageTestContent = value;
                RaisePropertyChanged();
            }
        }

        public string ProductLeakageTestContent
        {
            get { return _productLeakageTestContent; }
            set
            {
                _productLeakageTestContent = value;
                RaisePropertyChanged();
            }
        }

        public bool SelectRecipeBtnIsEnabled_01
        {
            get => _selectRecipeBtnIsEnabled_01;
            set => SetProperty(ref _selectRecipeBtnIsEnabled_01, value);
        }

        public bool SelectRecipeBtnIsEnabled_02
        {
            get => _selectRecipeBtnIsEnabled_02;
            set => SetProperty(ref _selectRecipeBtnIsEnabled_02, value);
        }

        public bool Stop1IsEnabled
        {
            get => _stop1IsEnabled;
            set => SetProperty(ref _stop1IsEnabled, value);
        }

        public bool Stop2IsEnabled
        {
            get => _stop2IsEnabled;
            set => SetProperty(ref _stop2IsEnabled, value);
        }

        public bool StartWork1IsEnabled
        {
            get => _startWork1IsEnabled;
            set => SetProperty(ref _startWork1IsEnabled, value);
        }

        public bool StartWork2IsEnabled
        {
            get => _startWork2IsEnabled;
            set => SetProperty(ref _startWork2IsEnabled, value);
        }

        public bool Process1IsEnabled
        {
            get => _process1IsEnabled;
            set => SetProperty(ref _process1IsEnabled, value);
        }

        public bool Process2IsEnabled
        {
            get => _process2IsEnabled;
            set => SetProperty(ref _process2IsEnabled, value);
        }

        // 流程1参数启用状态属性
        public bool CycleCount01IsEnabled
        {
            get => _cycleCount01IsEnabled;
            set => SetProperty(ref _cycleCount01IsEnabled, value);
        }

        public bool VacuumValue01IsEnabled
        {
            get => _vacuumValue01IsEnabled;
            set => SetProperty(ref _vacuumValue01IsEnabled, value);
        }

        public bool VacuumHoldTime01IsEnabled
        {
            get => _vacuumHoldTime01IsEnabled;
            set => SetProperty(ref _vacuumHoldTime01IsEnabled, value);
        }

        public bool HeliumValue01IsEnabled
        {
            get => _heliumValue01IsEnabled;
            set => SetProperty(ref _heliumValue01IsEnabled, value);
        }

        public bool HeliumHoldTime01IsEnabled
        {
            get => _heliumHoldTime01IsEnabled;
            set => SetProperty(ref _heliumHoldTime01IsEnabled, value);
        }

        public bool FinalHeliumValue01IsEnabled
        {
            get => _finalHeliumValue01IsEnabled;
            set => SetProperty(ref _finalHeliumValue01IsEnabled, value);
        }

        public bool FinalHoldTime01IsEnabled
        {
            get => _finalHoldTime01IsEnabled;
            set => SetProperty(ref _finalHoldTime01IsEnabled, value);
        }

        // 流程2参数启用状态属性
        public bool CycleCount02IsEnabled
        {
            get => _cycleCount02IsEnabled;
            set => SetProperty(ref _cycleCount02IsEnabled, value);
        }

        public bool VacuumValue02IsEnabled
        {
            get => _vacuumValue02IsEnabled;
            set => SetProperty(ref _vacuumValue02IsEnabled, value);
        }

        public bool VacuumHoldTime02IsEnabled
        {
            get => _vacuumHoldTime02IsEnabled;
            set => SetProperty(ref _vacuumHoldTime02IsEnabled, value);
        }

        public bool HeliumValue02IsEnabled
        {
            get => _heliumValue02IsEnabled;
            set => SetProperty(ref _heliumValue02IsEnabled, value);
        }

        public bool HeliumHoldTime02IsEnabled
        {
            get => _heliumHoldTime02IsEnabled;
            set => SetProperty(ref _heliumHoldTime02IsEnabled, value);
        }

        public bool FinalHeliumValue02IsEnabled
        {
            get => _finalHeliumValue02IsEnabled;
            set => SetProperty(ref _finalHeliumValue02IsEnabled, value);
        }

        public bool FinalHoldTime02IsEnabled
        {
            get => _finalHoldTime02IsEnabled;
            set => SetProperty(ref _finalHoldTime02IsEnabled, value);
        }

        private string _workTime;//计时器

        private ProcessStep _currentStep_01; // 步骤指示器 高亮当前步骤背景
        private ProcessStep _currentStep_02; // 步骤指示器 高亮当前步骤背景

        public ProcessStep CurrentStep_01
        {
            get => _currentStep_01;
            set => SetProperty(ref _currentStep_01, value);
        }
        public ProcessStep CurrentStep_02
        {
            get => _currentStep_02;
            set => SetProperty(ref _currentStep_02, value);
        }

        public string WorkTime
        {
            get => _workTime;
            set => SetProperty(ref _workTime, value);
        }

        private string _recipeNameContent_01; //配方名称按钮——01
        private string _recipeNameContent_02; //配方名称按钮——02

        public string RecipeNameContent_02
        {
            get => _recipeNameContent_02;
            set => SetProperty(ref _recipeNameContent_02, value);
        }

        public string RecipeNameContent_01
        {
            get => _recipeNameContent_01;
            set => SetProperty(ref _recipeNameContent_01, value);
        }


        // 公开属性，用于绑定到视图
        public DeviceRunningState CurrentState
        {
            get => _currentState;
            set => SetProperty(ref _currentState, value);
        }

        // 实时值
        // 流程1
        public int CycleCountRealTime_01
        {
            get => _cycleCountRealTime_01;
            set => SetProperty(ref _cycleCountRealTime_01, value);
        }
        public double VacuumRealTime_01
        {
            get => _vacuumRealTime_01;
            set => SetProperty(ref _vacuumRealTime_01, value);
        }
        public int VacuumTimeRealTime_01
        {
            get => _vacuumTimeRealTime_01;
            set
            {
                //_vacuumTimeRealTime_01 = value;
                //RaisePropertyChanged();
                // 这种写法是错误的 应该传递属性名称字符串
                //RaisePropertyChanged(VacuumHoldTimeCountdown_01.ToString());

                if (SetProperty(ref _vacuumTimeRealTime_01, value))
                {
                    // 当这个属性变化时，通知倒计时属性也变化了
                    RaisePropertyChanged(nameof(VacuumHoldTimeCountdown_01));
                }
            }
        }
        public double HeliumRealTime_01
        {
            get => _heliumRealTime_01;
            set => SetProperty(ref _heliumRealTime_01, value);
        }
        public int HeliumTimeRealTime_01
        {
            get => _heliumTimeRealTime_01;
            set
            {
                if (SetProperty(ref _heliumTimeRealTime_01, value))
                {
                    RaisePropertyChanged(nameof(HeliumHoldTimeCountdown_01));
                }
            }
        }
        public double FinalHeliumRealTime_01
        {
            get => _finalHeliumRealTime_01;
            set => SetProperty(ref _finalHeliumRealTime_01, value);
        }
        public int FinalHeliumTimeRealTime_01
        {
            get => _finalHeliumTimeRealTime_01;
            set
            {
                if (SetProperty(ref _finalHeliumTimeRealTime_01, value))
                {
                    RaisePropertyChanged(nameof(FinalHoldTimeCountdown_01));
                }
            }
        }
        // 流程2
        public int CycleCountRealTime_02
        {
            get => _cycleCountRealTime_02;
            set => SetProperty(ref _cycleCountRealTime_02, value);
        }
        public double VacuumRealTime_02
        {
            get => _vacuumRealTime_02;
            set => SetProperty(ref _vacuumRealTime_02, value);
        }
        public int VacuumTimeRealTime_02
        {
            get => _vacuumTimeRealTime_02;
            set
            {
                if (SetProperty(ref _vacuumTimeRealTime_02, value))
                {
                    RaisePropertyChanged(nameof(VacuumHoldTimeCountdown_02));
                }
            }
        }
        public double HeliumRealTime_02
        {
            get => _heliumRealTime_02;
            set => SetProperty(ref _heliumRealTime_02, value);
        }
        public int HeliumTimeRealTime_02
        {
            get => _heliumTimeRealTime_02;
            set
            {
                if (SetProperty(ref _heliumTimeRealTime_02, value))
                {
                    RaisePropertyChanged(nameof(HeliumHoldTimeCountdown_02));
                }
            }
        }
        public double FinalHeliumRealTime_02
        {
            get => _finalHeliumRealTime_02;
            set => SetProperty(ref _finalHeliumRealTime_02, value);
        }
        public int FinalHeliumTimeRealTime_02
        {
            get => _finalHeliumTimeRealTime_02;
            set
            {
                if (SetProperty(ref _finalHeliumTimeRealTime_02, value))
                {
                    RaisePropertyChanged(nameof(FinalHoldTimeCountdown_02));
                }
            }
        }

        public double FinalHoldTimeBarValue_02
        {
            get => _finalHoldTimeBarValue_02;
            set => SetProperty(ref _finalHoldTimeBarValue_02, value);
        }

        public double FinalHeliumBarValue_02
        {
            get => _finalHeliumBarValue_02;
            set => SetProperty(ref _finalHeliumBarValue_02, value);
        }

        public double HeliumHoldTimeBarValue_02
        {
            get => _heliumHoldTimeBarValue_02;
            set => SetProperty(ref _heliumHoldTimeBarValue_02, value);
        }

        public double HeliumBarValue_02
        {
            get => _heliumBarValue_02;
            set => SetProperty(ref _heliumBarValue_02, value);
        }

        public double VacuumHoldTimeBarValue_02
        {
            get => _vacuumHoldTimeBarValue_02;
            set => SetProperty(ref _vacuumHoldTimeBarValue_02, value);
        }

        public double VacuumBarValue_02
        {
            get => _vacuumBarValue_02;
            set => SetProperty(ref _vacuumBarValue_02, value);
        }

        public double CycleCountBarValue_02
        {
            get => _cycleCountBarValue_02;
            set => SetProperty(ref _cycleCountBarValue_02, value);
        }

        public double FinalHoldTimeBarValue_01
        {
            get => _finalHoldTimeBarValue_01;
            set => SetProperty(ref _finalHoldTimeBarValue_01, value);
        }

        public double FinalHeliumBarValue_01
        {
            get => _finalHeliumBarValue_01;
            set => SetProperty(ref _finalHeliumBarValue_01, value);
        }

        public double HeliumHoldTimeBarValue_01
        {
            get => _heliumHoldTimeBarValue_01;
            set => SetProperty(ref _heliumHoldTimeBarValue_01, value);
        }

        public double HeliumBarValue_01
        {
            get => _heliumBarValue_01;
            set => SetProperty(ref _heliumBarValue_01, value);
        }


        public double VacuumHoldTimeBarValue_01
        {
            get => _vacuumHoldTimeBarValue_01;
            set => SetProperty(ref _vacuumHoldTimeBarValue_01, value);
        }

        public double VacuumBarValue_01
        {
            get => _vacuumBarValue_01;
            set => SetProperty(ref _vacuumBarValue_01, value);
        }

        public double CycleCountBarValue_01
        {
            get => _cycleCountBarValue_01;
            set => SetProperty(ref _cycleCountBarValue_01, value);
        }

        // 用户键入参数 配方参数
        public int CycleCount_01
        {
            get => _cycleCount_01;
            set => SetProperty(ref _cycleCount_01, value);
        }

        public double VacuumValue_01
        {
            get => _vacuumValue_01;
            set => SetProperty(ref _vacuumValue_01, value);
        }

        public int VacuumHoldTime_01
        {
            get => _vacuumHoldTime_01;
            set
            {
                if (SetProperty(ref _vacuumHoldTime_01, value))
                {
                    RaisePropertyChanged(nameof(VacuumHoldTimeCountdown_01));
                }
            }
        }

        public double HeliumValue_01
        {
            get => _heliumValue_01;
            set => SetProperty(ref _heliumValue_01, value);
        }

        public int HeliumHoldTime_01
        {
            get => _heliumHoldTime_01;
            set
            {
                if (SetProperty(ref _heliumHoldTime_01, value))
                {
                    RaisePropertyChanged(nameof(HeliumHoldTimeCountdown_01));
                }
            }
        }

        public double FinalHeliumValue_01
        {
            get => _finalHeliumValue_01;
            set => SetProperty(ref _finalHeliumValue_01, value);
        }

        public int FinalHoldTime_01
        {
            get => _finalHoldTime_01;
            set
            {
                if (SetProperty(ref _finalHoldTime_01, value))
                {
                    RaisePropertyChanged(nameof(FinalHoldTimeCountdown_01));
                }
            }
        }

        public int CycleCount_02
        {
            get => _cycleCount_02;
            set => SetProperty(ref _cycleCount_02, value);
        }

        public double VacuumValue_02
        {
            get => _vacuumValue_02;
            set => SetProperty(ref _vacuumValue_02, value);
        }

        public int VacuumHoldTime_02
        {
            get => _vacuumHoldTime_02;
            set
            {
                if (SetProperty(ref _vacuumHoldTime_02, value))
                {
                    RaisePropertyChanged(nameof(VacuumHoldTimeCountdown_02));
                }
            }
        }

        public double HeliumValue_02
        {
            get => _heliumValue_02;
            set => SetProperty(ref _heliumValue_02, value);
        }

        public int HeliumHoldTime_02
        {
            get => _heliumHoldTime_02;
            set
            {
                if (SetProperty(ref _heliumHoldTime_02, value))
                {
                    RaisePropertyChanged(nameof(HeliumHoldTimeCountdown_02));
                }
            }
        }

        public double FinalHeliumValue_02
        {
            get => _finalHeliumValue_02;
            set => SetProperty(ref _finalHeliumValue_02, value);
        }

        public int FinalHoldTime_02
        {
            get => _finalHoldTime_02;
            set
            {
                if (SetProperty(ref _finalHoldTime_02, value))
                {
                    RaisePropertyChanged(nameof(FinalHoldTimeCountdown_02));
                }
            }
        }

        // 工位用
        //public bool IsCheckedProduct01
        //{
        //    get => _isCheckedProduct01;
        //    set => SetProperty(ref _isCheckedProduct01, value);
        //}
        //public bool IsCheckedProduct02
        //{
        //    get => _isCheckedProduct02;
        //    set => SetProperty(ref _isCheckedProduct02, value);
        //}
        //public bool IsCheckedProduct03
        //{
        //    get => _isCheckedProduct03;
        //    set => SetProperty(ref _isCheckedProduct03, value);
        //}
        //public bool IsCheckedProduct04
        //{
        //    get => _isCheckedProduct04;
        //    set => SetProperty(ref _isCheckedProduct04, value);
        //}
        //public bool IsCheckedProduct05
        //{
        //    get => _isCheckedProduct05;
        //    set => SetProperty(ref _isCheckedProduct05, value);
        //}
        //public bool IsCheckedProduct06
        //{
        //    get => _isCheckedProduct06;
        //    set => SetProperty(ref _isCheckedProduct06, value);
        //}

        public ICommand StartWorkCommand { get; private set; }
        public ICommand StopWorkCommand { get; private set; }
        public ICommand SelectRecipeCommand { get; private set; }
        public ICommand DeviceLeakageTestCommand { get; set; }
        public ICommand ProductLeakageTestCommand { get; set; }

        #endregion

        public HomeViewModel(UserModel userModel, ShellViewModel shellViewModel)
        {
            _productModel = new ProductModel();
            _currentUser = userModel;
            _shellViewModel = shellViewModel;

            // 测试用 更新设备状态 0 停止状态 1 抽真空状态 2 充氦气状态 3 排气状态
            UpdateDeviceAnimation(0);
            //UpdateDeviceAnimation(1);
            //UpdateDeviceAnimation(2);
            //UpdateDeviceAnimation(3);
            CurrentState = DeviceRunningState.StopState;
            CurrentStep_01 = ProcessStep.Pending;
            CurrentStep_02 = ProcessStep.Pending;

            // 订阅
            _shellViewModel.UserInfoUpdate += OnUserInfoUpdate;
            // 订阅并立即获取状态 设备是否连接
            AppEventCenter.SubscribeWithLastState(OnCommStateChanged);

            // 使用带参数的 RelayCommand
            StartWorkCommand = new RelayCommand<string>(ExecuteStartWork);
            StopWorkCommand = new RelayCommand<string>(ExecuteStopWork);
            SelectRecipeCommand = new RelayCommand<string>(ExecuteSelectRecipe);
            DeviceLeakageTestCommand = new RelayCommand(DeviceLeakageTestExecute);
            ProductLeakageTestCommand = new RelayCommand(ProductLeakageTestExecute);

            // 初始化工作流程上的参数数据
            InitWorkProcessParameters();
            //计时器
            InitializeTimers();
            //初始化
            SetProcess1TxtEnabled(true);
            SetProcess2TxtEnabled(true);
            Process1IsEnabled = true;
            Process2IsEnabled = true;
            StartWork1IsEnabled = true;
            StartWork2IsEnabled = true;
            Stop1IsEnabled = false;
            Stop2IsEnabled = false;

        }


        #region 工作

        #region 停止工作
        /// <summary>
        /// 停止工作
        /// </summary>
        /// <param name="obj"></param>
        private void ExecuteStopWork(string obj)
        {
            switch (obj)
            {
                case "1":
                    // 流程一停止工作
                    //停止管路图动画
                    UpdateDeviceAnimation(0);
                    StopProcess1();
                    break;
                case "2":
                    // 流程二停止工作
                    UpdateDeviceAnimation(0);
                    StopProcess2();
                    break;
            }
        }

        private void StopProcess2()
        {
            //启用
            SetProcess2TxtEnabled(true);
            Process1IsEnabled = true;//启用流程一按钮
            StartWork2IsEnabled = true;//启用流程开始工作按钮
            Stop2IsEnabled = false;

            //停止计时器
            StopProcessTimer();
            //进度条恢复为0
            ResetAllProgress2Bars();
            //更新工作工位是否有产品工作
            EnableWorkstationButton();
            //指示灯
            CurrentState = DeviceRunningState.StopState;
            // 高亮
            CurrentStep_01 = ProcessStep.Pending;
            CurrentStep_02 = ProcessStep.Pending;

            //取消任务
            _cts.Cancel();
        }

        private void StopProcess1()
        {
            //启用
            SetProcess1TxtEnabled(true);
            Process2IsEnabled = true;//启用流程二按钮
            StartWork1IsEnabled = true;//启用流程开始工作按钮
            Stop1IsEnabled = false;

            //停止计时器
            StopProcessTimer();
            //进度条恢复为0
            ResetAllProgress1Bars();
            //更新工作工位是否有产品工作---启用设备按钮
            EnableWorkstationButton();
            //指示灯
            CurrentState = DeviceRunningState.StopState;
            // 高亮
            CurrentStep_01 = ProcessStep.Pending;
            CurrentStep_02 = ProcessStep.Pending;

            //取消任务
            _cts.Cancel();

        }

        #endregion

        #region 开启工艺流程前 检测 1.非法参数 2.设备连接状态 3.系统运行状态
        // 1
        /// <summary>
        /// 检查流程参数是否有效（是否大于0）
        /// </summary>
        private (bool isValid, string errorMessage) ValidateProcessParameters(int processNumber)
        {
            try
            {
                switch (processNumber)
                {
                    case 1:
                        return ValidateProcess1Parameters();
                    case 2:
                        return ValidateProcess2Parameters();
                    default:
                        return (false, "不支持的流程编号");
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), $"[参数验证]|验证流程{processNumber}参数时发生异常", ex, _currentUser?.UserAccount);
                return (false, $"参数验证异常: {ex.Message}");
            }
        }

        /// <summary>
        /// 验证流程1参数是否大于0
        /// </summary>
        private (bool isValid, string errorMessage) ValidateProcess1Parameters()
        {
            if (CycleCount_01 <= 0)
                return (false, "流程1循环次数必须大于0");

            if (VacuumValue_01 <= 0)
                return (false, "流程1真空度必须大于0");

            if (VacuumHoldTime_01 <= 0)
                return (false, "流程1真空保持时间必须大于0");

            if (HeliumValue_01 <= 0)
                return (false, "流程1充氦气值必须大于0");

            if (HeliumHoldTime_01 <= 0)
                return (false, "流程1充氦气保持时间必须大于0");

            if (FinalHeliumValue_01 <= 0)
                return (false, "流程1最后充氦气值必须大于0");

            if (FinalHoldTime_01 <= 0)
                return (false, "流程1最后保压时间必须大于0");

            return (true, "流程1参数验证通过");
        }

        /// <summary>
        /// 验证流程2参数是否大于0
        /// </summary>
        private (bool isValid, string errorMessage) ValidateProcess2Parameters()
        {
            if (CycleCount_02 <= 0)
                return (false, "流程2循环次数必须大于0");

            if (VacuumValue_02 <= 0)
                return (false, "流程2真空度必须大于0");

            if (VacuumHoldTime_02 <= 0)
                return (false, "流程2真空保持时间必须大于0");

            if (HeliumValue_02 <= 0)
                return (false, "流程2充氦气值必须大于0");

            if (HeliumHoldTime_02 <= 0)
                return (false, "流程2充氦气保持时间必须大于0");

            if (FinalHeliumValue_02 <= 0)
                return (false, "流程2最后充氦气值必须大于0");

            if (FinalHoldTime_02 <= 0)
                return (false, "流程2最后保压时间必须大于0");

            return (true, "流程2参数验证通过");
        }

        // 2
        private CommState _isDeviceComm = CommState.Disconnected;
        public CommState IsDeviceComm
        {
            get => _isDeviceComm;
            set => SetProperty(ref _isDeviceComm, value);
        }

        /// <summary>
        /// 检查设备硬件连接状态
        /// </summary>
        private (bool isConnected, string errorMessage) CheckDeviceHardwareConnection()
        {
            try
            {
                // 检查设备连接状态
                if (IsDeviceComm == CommState.Disconnected)
                    return (false, "设备未连接");

                return (true, "设备连接正常");
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), "[设备连接检查]|检查设备连接状态时发生异常", ex, _currentUser?.UserAccount);
                return (false, $"设备连接检查异常: {ex.Message}");
            }
        }

        private void OnCommStateChanged(object sender, CommStateChangeEventArgs e)
        {
            // sender 可能为 null（历史状态），也可能是实际的发送者（实时事件）
            if (sender == null)
            {
                Debug.WriteLine("收到历史状态: " + e.State);
            }
            else
            {
                Debug.WriteLine("收到实时状态更新: " + e.State);
            }

            // 赋值
            IsDeviceComm = e.State;
        }

        // 3
        /// <summary>
        /// 检查系统运行状态
        /// </summary>
        private (bool canStart, string errorMessage) CheckSystemRunningStatus(int processNumber)
        {
            try
            {
                // 检查设备是否正在运行其他流程
                if (Process1IsEnabled == false && processNumber == 2)
                    return (false, "流程1正在运行，无法启动流程2");

                if (Process2IsEnabled == false && processNumber == 1)
                    return (false, "流程2正在运行，无法启动流程1");

                // 检查漏率检测状态
                if (IsDeviceLeakageTesting || IsProductLeakageTesting)
                    return (false, "正在进行漏率检测，请等待检测完成");

                // 检查工位状态
                //if (!CheckWorkstationStatus())
                //    return (false, "没有可用的工位，请先扫码分配产品");

                return (true, "系统状态正常");
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), $"[系统状态检查]|检查流程{processNumber}系统状态时发生异常", ex, _currentUser?.UserAccount);
                return (false, $"系统状态检查异常: {ex.Message}");
            }
        }

        /// <summary>
        /// 检查工位状态
        /// </summary>
        private bool CheckWorkstationStatus()
        {
            try
            {
                // 检查是否有至少一个工位被占用（有产品）
                // 当工位被占用时，IsEnableWorkstation_xx 为 false
                bool hasOccupiedWorkstation = !DeviceDataStore.IsEnableWorkstation_01 ||
                                              !DeviceDataStore.IsEnableWorkstation_02 ||
                                              !DeviceDataStore.IsEnableWorkstation_03 ||
                                              !DeviceDataStore.IsEnableWorkstation_04 ||
                                              !DeviceDataStore.IsEnableWorkstation_05 ||
                                              !DeviceDataStore.IsEnableWorkstation_06;
                return hasOccupiedWorkstation;
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), "[检查工位状态]|检查工位状态时发生异常", ex, _currentUser?.UserAccount);
                return false;
            }
        }
        #endregion

        #region 开始工作
        /// <summary>
        /// 开始工作
        /// </summary>
        /// <param name="obj"></param>
        private async void ExecuteStartWork(string obj)
        {
            try
            {
                #region 检测部分 如果报错 直接注释掉也可以
                int processNumber = int.Parse(obj);

                // 1.验证参数是否大于0
                var validationResult = ValidateProcessParameters(processNumber);
                if (!validationResult.isValid)
                {
                    MsgBoxHelper.Warning(validationResult.errorMessage);
                    LogHelper.Warn(this.GetType(), $"[参数验证]|流程{processNumber}参数验证失败: {validationResult.errorMessage}", _currentUser?.UserAccount);
                    return;
                }

                // 2.检查设备硬件连接状态
                var connectionResult = CheckDeviceHardwareConnection();
                if (!connectionResult.isConnected)
                {
                    MsgBoxHelper.Warning(connectionResult.errorMessage);
                    LogHelper.Warn(this.GetType(), $"[设备连接检查]|流程{processNumber}启动前设备连接检查失败: {connectionResult.errorMessage}", _currentUser?.UserAccount);
                    return;
                }

                // 3.检查系统运行状态
                var systemStatusResult = CheckSystemRunningStatus(processNumber);
                if (!systemStatusResult.canStart)
                {
                    MsgBoxHelper.Warning(systemStatusResult.errorMessage);
                    LogHelper.Warn(this.GetType(), $"[系统状态检查]|流程{processNumber}启动前系统状态检查失败: {systemStatusResult.errorMessage}", _currentUser?.UserAccount);
                    return;
                }
                #endregion

                // 4.检测完毕后 没有问题 就开始工作
                switch (obj)
                {
                    case "1":
                        // 流程一开始工作
                        StartProcessTimer();
                        await StartProcess1();
                        break;
                    case "2":
                        // 流程二开始工作
                        StartProcessTimer();
                        await StartProcess2();
                        break;
                }

                // 启动工艺时 加个日志 不加也行
                LogHelper.Info(this.GetType(), $"[开启工艺流程]|流程{obj}启动成功", _currentUser?.UserAccount);
            }
            catch (Exception ex)
            {
                MsgBoxHelper.Error($"启动流程时发生错误: {ex.Message}");
                // 启动工艺失败 要加的
                LogHelper.Error(this.GetType(), $"[开启工艺流程]|启动流程{obj}时发生异常", ex, _currentUser?.UserAccount);
            }
        }


        /// <summary>
        /// 流程一开始工作
        /// </summary>
        /// <returns></returns>
        private async Task StartProcess1()
        {
            try
            {
                _cts = new CancellationTokenSource();
                var cancellationToken = _cts.Token;

                LogHelper.Info(this.GetType(), "[启动流程1]|流程1开始执行", _currentUser?.UserAccount);
                // 执行自动流程（传递取消令牌）
                await AutoExecuteProcess1(cancellationToken);

            }
            catch (Exception ex)
            {
                MsgBoxHelper.Error($"流程1执行异常: {ex.Message}");
                LogHelper.Error(this.GetType(), "[流程1异常]|流程1执行异常", ex, _currentUser?.UserAccount);
            }
            finally
            {

            }
        }

        /// <summary>
        /// 流程二开始工作 
        /// </summary>
        /// <returns></returns>
        private async Task StartProcess2()
        {
            try
            {
                _cts = new CancellationTokenSource();
                var cancellationToken = _cts.Token;

                LogHelper.Info(this.GetType(), "[启动流程2]|流程2开始执行", _currentUser?.UserAccount);
                // 执行自动流程（传递取消令牌）
                await AutoExecuteProcess2(cancellationToken);

            }
            catch (Exception ex)
            {
                MsgBoxHelper.Error($"流程2执行异常: {ex.Message}");
                LogHelper.Error(this.GetType(), "[流程2异常]|流程2执行异常", ex, _currentUser?.UserAccount);
            }
            finally
            {
                _cts?.Dispose();
                _cts = null;
            }
        }

        /// <summary>
        /// 流程一自动运行
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        private async Task AutoExecuteProcess1(CancellationToken cancellationToken)
        {
            try
            {
                //指示灯
                CurrentState = DeviceRunningState.RunState;
                //禁用
                SetProcess1TxtEnabled(false);//文本框
                Process2IsEnabled = false;//禁用流程二按钮
                StartWork1IsEnabled = false; //禁用开始工作按钮
                Stop1IsEnabled = true;

                for (int i = 0; i < CycleCount_01; i++)
                {
                    //每次执行之前都清除一遍进度条 除了循环次数的进度条
                    ResetProgress1Bars();
                    CycleCountRealTime_01 = i + 1; // 当前循环次数 待验证
                    CycleCountBarValue_01 = (double)(i + 1) / CycleCount_01 * 100;
                    //执行流程一循环体
                    //开始抽真空
                    CurrentStep_01 = ProcessStep.Vacuum;
                    await EvacuateVacuum(
                            VacuumValue_01,
                            progress => VacuumBarValue_01 = progress,
                            progress => VacuumRealTime_01 = progress,
                            cancellationToken);
                    //抽真空保持时间
                    CurrentStep_01 = ProcessStep.VacuumHold;
                    //await HoldVacuumTime(VacuumHoldTime_01, cancellationToken);
                    await HoldTimeWithProgress(
                       VacuumHoldTime_01,
                       progress => VacuumHoldTimeBarValue_01 = progress,
                       progress => VacuumTimeRealTime_01 = progress,
                       cancellationToken);
                    //开始充氦气
                    CurrentStep_01 = ProcessStep.Helium;
                    await EvacuateHelium(
                        HeliumValue_01,
                        progress => HeliumBarValue_01 = progress,
                        progress => HeliumRealTime_01 = progress,
                        cancellationToken);
                    //充氦气保持时间
                    CurrentStep_01 = ProcessStep.HeliumHold;
                    //await HoldHeliumTime(HeliumHoldTime_01, cancellationToken);
                    await HoldTimeWithProgress(
                      HeliumHoldTime_01,
                      progress => HeliumHoldTimeBarValue_01 = progress,
                      progress => HeliumTimeRealTime_01 = progress,
                      cancellationToken);
                    //排气
                    await EvacuatVent(cancellationToken);
                }
                //最后充氦气
                CurrentStep_01 = ProcessStep.FinalHelium;
                await EvacuateHelium(
                    FinalHeliumValue_01,
                    progress => FinalHeliumBarValue_01 = progress,
                    progress => FinalHeliumRealTime_01 = progress,
                    cancellationToken);
                //充氦气保压时间
                CurrentStep_01 = ProcessStep.FinalHeliumHold;
                //await FinalHoldHeliumTime(FinalHoldTime_01, cancellationToken);
                await HoldTimeWithProgress(
                      FinalHoldTime_01,
                      progress => FinalHoldTimeBarValue_01 = progress,
                      progress => FinalHeliumTimeRealTime_01 = progress,
                      cancellationToken);
                //流程结束
                CurrentState = DeviceRunningState.TipState;
                MessageBox.Show("---流程1执行完成---");

                if (!cancellationToken.IsCancellationRequested)
                {
                    //正常加工完成

                    //_cts.Cancel();//取消任务
                    UpdateDeviceAnimation(0);
                    //停止计时器
                    //StopProcessTimer();
                    _processTimer.Stop();
                    UpdateProductInfo(1, 1);
                }

            }
            catch (OperationCanceledException ex)
            {
                //手动停止
                UpdateProductInfo(2, 1);
            }
            catch (Exception ex)
            {
                //其他异常
            }

        }

        /// <summary>
        /// 流程二自动运行
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        private async Task AutoExecuteProcess2(CancellationToken cancellationToken)
        {
            //指示灯
            CurrentState = DeviceRunningState.RunState;
            //禁用
            SetProcess2TxtEnabled(false);//文本框
            Process1IsEnabled = false;//禁用流程一按钮
            StartWork2IsEnabled = false;//禁用开始工作按钮
            Stop2IsEnabled = true;

            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    //开始抽真空
                    CurrentStep_02 = ProcessStep.Vacuum;
                    await EvacuateVacuum(
                         VacuumValue_02,
                         progress => VacuumBarValue_02 = progress,
                         progress => VacuumRealTime_02 = progress,
                         cancellationToken);
                    //抽真空保持时间
                    CurrentStep_02 = ProcessStep.VacuumHold;
                    await HoldTimeWithProgress(
                          VacuumHoldTime_02,
                          progress => VacuumHoldTimeBarValue_02 = progress, // 使用传入的进度条更新Action
                          progress => VacuumTimeRealTime_02 = progress,
                          cancellationToken);

                    //循环体
                    for (int i = 0; i < CycleCount_02; i++)
                    {
                        //每次执行之前都清除一遍进度条循环内部程序 除了循环次数的进度条
                        ResetProgress2Bars();
                        CycleCountRealTime_02 = i + 1; // 当前循环次数 待验证
                        CycleCountBarValue_02 = (double)(i + 1) / CycleCount_02 * 100;
                        //执行流程二循环体
                        //开始充氦气
                        CurrentStep_02 = ProcessStep.Helium;
                        await EvacuateHelium(
                            HeliumValue_02,
                            progress => HeliumBarValue_02 = progress,
                            progress => HeliumRealTime_02 = progress,
                            cancellationToken);
                        //充氦气保持时间
                        CurrentStep_02 = ProcessStep.HeliumHold;
                        await HoldTimeWithProgress(
                              HeliumHoldTime_02,
                              progress => HeliumHoldTimeBarValue_02 = progress,
                              progress => HeliumTimeRealTime_02 = progress,
                              cancellationToken);
                        //排气
                        await EvacuatVent(cancellationToken);
                    }
                    //最后充氦气
                    CurrentStep_02 = ProcessStep.FinalHelium;
                    await EvacuateHelium(
                        FinalHeliumValue_02,
                        progress => FinalHeliumBarValue_02 = progress,
                        progress => FinalHeliumRealTime_02 = progress,
                        cancellationToken);
                    //最后充氦气保压时间
                    CurrentStep_02 = ProcessStep.FinalHeliumHold;
                    await HoldTimeWithProgress(
                              FinalHoldTime_02,
                              progress => FinalHoldTimeBarValue_02 = progress,
                              progress => FinalHeliumTimeRealTime_02 = progress,
                              cancellationToken);
                    //流程结束
                    CurrentState = DeviceRunningState.TipState;
                    MessageBox.Show("---流程2执行完成---");
                    if (!cancellationToken.IsCancellationRequested)
                    {
                        //正常加工完成

                        //_cts.Cancel();//取消任务
                        UpdateDeviceAnimation(0);
                        //停止计时器
                        //StopProcessTimer();
                        _processTimer.Stop();
                        UpdateProductInfo(1, 2);
                    }
                }
                catch (OperationCanceledException ex)
                {
                    UpdateProductInfo(2, 2);
                }
                catch (Exception ex)
                {
                    //其他异常
                }
            }
        }
        #endregion

        #region 计时器
        /// <summary>
        /// 初始化计时器
        /// </summary>
        private void InitializeTimers()
        {
            // 计时器
            _processTimer = new DispatcherTimer();
            _processTimer.Interval = TimeSpan.FromSeconds(1); // 每秒更新一次
            _processTimer.Tick += (sender, e) =>
            {
                _elapsedTime = _elapsedTime.Add(TimeSpan.FromSeconds(1));
                WorkTime = $"{_elapsedTime.Hours:D2}:{_elapsedTime.Minutes:D2}:{_elapsedTime.Seconds:D2}";
            };
            WorkTime = "00:00:00";
        }

        /// <summary>
        /// 启动计时器
        /// </summary>
        private void StartProcessTimer()
        {
            _elapsedTime = TimeSpan.Zero;
            WorkTime = "00:00:00";
            _processTimer?.Start();
        }

        /// <summary>
        /// 停止计时器
        /// </summary>
        private async void StopProcessTimer()
        {
            _processTimer?.Stop();
            // 重置时间为0
            await Task.Delay(200);
            _elapsedTime = TimeSpan.Zero;
            WorkTime = "00:00:00";
        }


        #endregion

        #region 通用方法

        /// <summary>
        /// 排气
        /// </summary>
        /// <returns></returns>
        private async Task EvacuatVent(CancellationToken cancellationToken)
        {

            //排气流程
            MessageBox.Show("---开始排气---");
            UpdateDeviceAnimation(3);
            await Task.Delay(5000, cancellationToken);
        }

        /// <summary>
        /// 充氦气
        /// </summary>
        /// <param name="heliumValue_01"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        private async Task EvacuateHelium(double HeliumValue, Action<double> updateProgressAction, Action<double> updateProgressAction2, CancellationToken cancellationToken)
        {
            UpdateDeviceAnimation(2);
            try
            {
                while (!cancellationToken.IsCancellationRequested)
                {
                    double currentValue = GetActualHeliumValue();  // 直接调用获取氦气值
                    updateProgressAction?.Invoke(CalculateProcessBar(currentValue, HeliumValue));
                    updateProgressAction2?.Invoke(currentValue);

                    if (currentValue >= HeliumValue)
                    {
                        break;
                    }

                    // 等待一段时间后再次检查
                    await Task.Delay(100, cancellationToken);
                }
            }
            catch (OperationCanceledException)
            {
                // 操作被取消
                throw;
            }
            catch (Exception ex)
            {
                throw new Exception($"充气过程中发生错误: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 抽真空（通用方法）
        /// </summary>
        /// <param name="vacuumValue">目标真空度</param>
        /// <param name="updateProgressAction">更新进度条的Action</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns></returns>
        private async Task EvacuateVacuum(double vacuumValue, Action<double> updateProgressAction, Action<double> updateProgressAction2, CancellationToken cancellationToken)
        {
            try
            {
                //管路图
                UpdateDeviceAnimation(1);
                double initialVacuum = GetActualVacuumValue();//压力初始值

                // 判断是否需要分阶段抽真空
                if (initialVacuum <= 10 && vacuumValue > 100)
                //if (initialVacuum > 10 && vacuumValue <= 10)
                {
                    // 先用机械泵抽到10Pa，再启动分子泵继续抽到目标值
                    await EvacuateVacuumStaged(vacuumValue, updateProgressAction, updateProgressAction2, cancellationToken);
                }
                else
                {
                    // 直接抽真空到目标值
                    string pumpType = vacuumValue >= 10 ? "机械泵" : "分子泵";
                    await EvacuateVacuumDirect(vacuumValue, updateProgressAction, updateProgressAction2, cancellationToken, pumpType);
                }
            }
            catch (OperationCanceledException)
            {
                // 操作被取消
                throw;
            }
            catch (TimeoutException ex)
            {
                LogHelper.Error(this.GetType(), "[抽真空超时]|抽真空超时", ex, _currentUser?.UserAccount);
                MsgBoxHelper.Error($"抽真空超时: {ex.Message}");
                throw;
            }
            catch (Exception ex)
            {
            }
        }

        /// <summary>
        /// 分阶段抽真空（先机械泵后分子泵）
        /// </summary>
        private async Task EvacuateVacuumStaged(double finalVacuumValue, Action<double> updateProgressAction, Action<double> updateProgressAction2, CancellationToken cancellationToken)
        {
            // 第一阶段：使用机械泵抽到10Pa
            //打开机械泵+阀门

            await EvacuateVacuumDirect(10, updateProgressAction, updateProgressAction2, cancellationToken, "机械泵");
            // 第二阶段：启动分子泵抽到最终目标值
            await EvacuateVacuumDirect(finalVacuumValue, updateProgressAction, updateProgressAction2, cancellationToken, "分子泵");
            // 抽真空完成后关闭机械泵


        }

        /// <summary>
        /// 直接抽真空到目标值（带超时控制）
        /// </summary>
        private async Task EvacuateVacuumDirect(double vacuumValue, Action<double> updateProgressAction, Action<double> updateProgressAction2, CancellationToken cancellationToken, string pumpType)
        {
            // 设置超时时间
            int timeoutSeconds = GetVacuumTimeout(vacuumValue);
            DateTime startTime = DateTime.Now;
            DateTime timeoutTime = startTime.AddSeconds(timeoutSeconds);

            // 持续抽真空直到达到目标值或被取消或超时
            while (!cancellationToken.IsCancellationRequested && DateTime.Now < timeoutTime)
            {
                double currentVacuum = GetActualVacuumValue();
                //进度条
                updateProgressAction?.Invoke(CalculateProcessBar(currentVacuum, vacuumValue));
                // 实时检测 获取当前真空度
                updateProgressAction2?.Invoke(currentVacuum);

                // 检查是否达到目标真空度
                //测试是>=   实际 <=
                if (currentVacuum >= vacuumValue)
                {
                    return;
                }
                await Task.Delay(100, cancellationToken);
            }
            // 检查是否超时
            if (DateTime.Now >= timeoutTime && !cancellationToken.IsCancellationRequested)
            {
                double currentVacuum = GetActualVacuumValue();
                string errorMsg = $"使用{pumpType}抽真空超时！目标: {vacuumValue}Pa，当前: {currentVacuum}Pa，超时时间: {timeoutSeconds}秒";
                throw new TimeoutException(errorMsg);
            }
        }

        /// <summary>
        /// 获取实际真空度
        /// </summary>
        /// <param name="v"></param>
        /// <returns></returns>
        private double GetActualVacuumValue()
        {
            return DeviceDataStore.VacuumValue_real;
        }

        /// <summary>
        /// 获取实际氦气
        /// </summary>
        /// <returns></returns>
        private double GetActualHeliumValue()
        {
            return DeviceDataStore.HeliumValue_real;
        }

        /// <summary>
        /// 计算进度条
        /// </summary>
        /// <param name="realValue"></param>
        /// <param name="setValue"></param>
        /// <returns></returns>
        private double CalculateProcessBar(double realValue, double setValue)
        {
            return realValue / setValue * 100;
        }

        /// <summary>
        /// 通用时间保持方法
        /// </summary>
        /// <param name="holdTime">保持时间（秒）</param>
        /// <param name="progressCallback">进度更新回调函数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns></returns>
        private async Task HoldTimeWithProgress(int holdTime, Action<double> progressCallback, Action<int> progressCallback2, CancellationToken cancellationToken)
        {
            try
            {
                DateTime startTime = DateTime.Now;
                DateTime endTime = startTime.AddSeconds(holdTime);

                // 初始化进度为0
                progressCallback?.Invoke(0);

                while (DateTime.Now < endTime && !cancellationToken.IsCancellationRequested)
                {
                    TimeSpan elapsed = DateTime.Now - startTime;
                    // 计算保持时间进度条 (已用时间/总时间)*100
                    double progress = (elapsed.TotalSeconds / holdTime) * 100;
                    progressCallback?.Invoke(Math.Min(100, progress)); // 确保不超过100

                    //progressCallback2?.Invoke(Math.Round(elapsed.TotalSeconds, 1)); // 保留1位小数
                    progressCallback2?.Invoke(Convert.ToInt32(elapsed.TotalSeconds));

                    // 每100毫秒更新一次进度
                    await Task.Delay(100, cancellationToken);
                }

                // 检查是否正常完成
                if (!cancellationToken.IsCancellationRequested)
                {
                    // 确保进度条达到100%
                    progressCallback?.Invoke(100);
                }
            }
            catch (OperationCanceledException)
            {
                // 操作被取消
                throw;
            }
            catch (Exception ex)
            {
                throw new Exception($"保持时间过程中发生错误: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 重置进度条（除循环次数进度条外的所有进度条清零）----流程一
        /// </summary>
        private void ResetProgress1Bars()
        {
            VacuumBarValue_01 = 0;
            VacuumHoldTimeBarValue_01 = 0;
            HeliumBarValue_01 = 0;
            HeliumHoldTimeBarValue_01 = 0;
        }
        /// <summary>
        /// 重置进度条（除循环次数进度条外的所有进度条清零）----流程二
        /// </summary>
        private void ResetProgress2Bars()
        {

            HeliumBarValue_02 = 0;
            HeliumHoldTimeBarValue_02 = 0;
        }

        /// <summary>
        /// 重置流程一所有进度条
        /// </summary>
        private void ResetAllProgress1Bars()
        {
            ResetProgress1Bars();
            CycleCountBarValue_01 = 0;
            FinalHeliumBarValue_01 = 0;
            FinalHoldTimeBarValue_01 = 0;
        }

        /// <summary>
        /// 重置流程二所有进度条
        /// </summary>
        private void ResetAllProgress2Bars()
        {
            ResetProgress2Bars();
            VacuumBarValue_02 = 0;
            VacuumHoldTimeBarValue_02 = 0;
            CycleCountBarValue_02 = 0;
            FinalHeliumBarValue_02 = 0;
            FinalHoldTimeBarValue_02 = 0;
        }

        /// <summary>
        /// 启用工位按钮
        /// </summary>
        private void EnableWorkstationButton()
        {
            DeviceDataStore.IsEnableWorkstation_01 = true;
            DeviceDataStore.IsEnableWorkstation_02 = true;
            DeviceDataStore.IsEnableWorkstation_03 = true;
            DeviceDataStore.IsEnableWorkstation_04 = true;
            DeviceDataStore.IsEnableWorkstation_05 = true;
            DeviceDataStore.IsEnableWorkstation_06 = true;
        }

        /// <summary>
        /// 启用或禁用流程1的参数
        /// </summary>
        /// <param name="isEnabled">是否启用</param>
        private void SetProcess1TxtEnabled(bool isEnabled)
        {
            //文本框输入框
            CycleCount01IsEnabled = isEnabled;
            VacuumValue01IsEnabled = isEnabled;
            VacuumHoldTime01IsEnabled = isEnabled;
            HeliumValue01IsEnabled = isEnabled;
            HeliumHoldTime01IsEnabled = isEnabled;
            FinalHeliumValue01IsEnabled = isEnabled;
            FinalHoldTime01IsEnabled = isEnabled;

            //选择配方按钮
            SelectRecipeBtnIsEnabled_01 = isEnabled;
        }

        /// <summary>
        /// 启用或禁用流程2的参数
        /// </summary>
        /// <param name="isEnabled">是否启用</param>
        private void SetProcess2TxtEnabled(bool isEnabled)
        {
            //文本框输入框
            CycleCount02IsEnabled = isEnabled;
            VacuumValue02IsEnabled = isEnabled;
            VacuumHoldTime02IsEnabled = isEnabled;
            HeliumValue02IsEnabled = isEnabled;
            HeliumHoldTime02IsEnabled = isEnabled;
            FinalHeliumValue02IsEnabled = isEnabled;
            FinalHoldTime02IsEnabled = isEnabled;

            //选择配方按钮
            SelectRecipeBtnIsEnabled_02 = isEnabled;
        }

        /// <summary>
        /// 获取抽真空超时时间
        /// </summary>
        /// <param name="targetVacuum">目标真空度</param>
        /// <returns>超时时间（秒）</returns>
        private int GetVacuumTimeout(double targetVacuum)
        {
            // 根据技术规格设置超时时间
            if (targetVacuum >= 10)        // 大气压到 10Pa：≤5min
                return 5 * 60;
            else if (targetVacuum >= 1e-4) // 10Pa 到 10^-4Pa：≤25min
                return 25 * 60;
            else if (targetVacuum >= 5e-6) // 5x10^-4Pa 到 5x10^-5Pa：≤10min
                return 10 * 60;
            else
                return 60 * 60; // 默认1小时
        }

        #endregion

        #region 更新产品信息
        /// <summary>
        /// 修改产品信息
        /// </summary>
        /// <param name="status">加工状态 0:正在加工 1:加工完成 2:加工异常/品质不符</param>
        /// <param name="recipeProcess">流程编号</param>
        private void UpdateProductInfo(int status, int recipeProcess)
        {
            try
            {
                // 根据流程编号设置对应的循环次数
                int cycleCount = 0;
                double pressureValue = 0;

                switch (recipeProcess)
                {
                    case 1:
                        cycleCount = CycleCount_01;
                        pressureValue = DeviceDataStore.HeliumValue_real; // 流程1的最终压力值
                        break;
                    case 2:
                        cycleCount = CycleCount_02;
                        pressureValue = DeviceDataStore.HeliumValue_real; // 流程2的最终压力值
                        break;
                    default:
                        cycleCount = 0;
                        pressureValue = 0;
                        break;
                }
                // 更新产品信息
                _productModel.ProcessStatus = status;
                _productModel.RecipeProcess = recipeProcess;
                _productModel.Operator = _currentUser.UserName;
                _productModel.EndTime = DateTime.Now;
                _productModel.ProcessTime = _elapsedTime; // 总加工时间
                _productModel.CycleCount = cycleCount; // 根据流程设置的循环次数
                _productModel.PressureValue = pressureValue.ToString("F3"); // 最后的产品压力值，保留2位小数


                // 更新数据库中的产品信息
                string updateSql = @"UPDATE product_info 
                            SET process_status = @processStatus,
                                recipe_process = @recipeProcess,
                                operator = @operatorName,
                                end_time = @endTime,
                                process_time = @processTime,
                                cycle_count = @cycleCount,
                                pressure_value = @pressureValue
                            WHERE process_status = 0;";

                List<MySqlParameter> parameters = new List<MySqlParameter>
                {
                    new MySqlParameter("@processStatus", status),
                    new MySqlParameter("@recipeProcess", recipeProcess),
                    new MySqlParameter("@operatorName", _currentUser.UserName),
                    new MySqlParameter("@endTime", DateTime.Now),
                    new MySqlParameter("@processTime", _elapsedTime),
                    new MySqlParameter("@cycleCount", cycleCount),
                    new MySqlParameter("@pressureValue", pressureValue.ToString("F3")),
                };

                // 执行更新操作
                int result = MysqlHelper.ExecuteNonQuery(updateSql, parameters.ToArray());
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), "[更新产品信息异常]|更新产品信息时发生异常", ex, _currentUser?.UserAccount);
            }
        }
        #endregion

        #region 选择配方
        /// <summary>
        /// 选择配方
        /// </summary>
        /// <param name="recipeProcesson">流程编号 ("1" 或 "2")</param>
        private void ExecuteSelectRecipe(string recipeProcesson)
        {
            try
            {
                // 打开配方选择窗体
                var selectRecipeWindow = new SelectRecipeView(recipeProcesson);

                // 创建 SelectRecipeViewModel 实例并传递参数
                var viewModel = new SelectRecipeViewModel(selectRecipeWindow, recipeProcesson);

                // 订阅配方选择事件（使用事件方式传递数据）
                viewModel.RecipeSelectedEvent += (sender, e) =>
                {
                    var selectedRecipe = e.SelectedRecipe;

                    // 根据流程编号设置对应的参数
                    switch (recipeProcesson)
                    {
                        case "1":
                            // 设置流程1的参数
                            CycleCount_01 = selectedRecipe.CycleCount;
                            VacuumValue_01 = string.IsNullOrEmpty(selectedRecipe.DrawValue) ? 0 : Convert.ToDouble(selectedRecipe.DrawValue);
                            VacuumHoldTime_01 = selectedRecipe.DrawKeepTime;
                            HeliumValue_01 = string.IsNullOrEmpty(selectedRecipe.PumpValue) ? 0 : Convert.ToDouble(selectedRecipe.PumpValue);
                            HeliumHoldTime_01 = selectedRecipe.PumpKeepTime;
                            FinalHeliumValue_01 = string.IsNullOrEmpty(selectedRecipe.StablePressureValue) ? 0 : Convert.ToDouble(selectedRecipe.StablePressureValue);
                            FinalHoldTime_01 = selectedRecipe.StablePressureKeepTime;
                            RecipeNameContent_01 = selectedRecipe.RecipeName;
                            ConfigHelper.SetValue("RecipeNameContent_01", selectedRecipe.RecipeName);
                            break;

                        case "2":
                            // 设置流程2的参数
                            CycleCount_02 = selectedRecipe.CycleCount;
                            VacuumValue_02 = string.IsNullOrEmpty(selectedRecipe.DrawValue) ? 0 : Convert.ToDouble(selectedRecipe.DrawValue);
                            VacuumHoldTime_02 = selectedRecipe.DrawKeepTime;
                            HeliumValue_02 = string.IsNullOrEmpty(selectedRecipe.PumpValue) ? 0 : Convert.ToDouble(selectedRecipe.PumpValue);
                            HeliumHoldTime_02 = selectedRecipe.PumpKeepTime;
                            FinalHeliumValue_02 = string.IsNullOrEmpty(selectedRecipe.StablePressureValue) ? 0 : Convert.ToDouble(selectedRecipe.StablePressureValue);
                            FinalHoldTime_02 = selectedRecipe.StablePressureKeepTime;
                            RecipeNameContent_02 = selectedRecipe.RecipeName;
                            ConfigHelper.SetValue("RecipeNameContent_02", selectedRecipe.RecipeName);
                            break;

                        default:
                            MessageBox.Show("不支持的流程编号", "错误", MessageBoxButton.OK, MessageBoxImage.Warning);
                            break;
                    }
                };

                // 设置 DataContext
                selectRecipeWindow.DataContext = viewModel;

                // 显示模态对话框
                selectRecipeWindow.ShowDialog();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载配方选择窗口时发生错误: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                LogHelper.Error(this.GetType(), "[选择配方异常]|加载配方选择窗口异常", ex, _currentUser?.UserAccount);
            }
        }

        /// <summary>
        /// 初始化当前工站所有参数
        /// </summary>
        private void InitWorkProcessParameters()
        {
            try
            {
                RecipeNameContent_01 = ConfigHelper.GetString("RecipeNameContent_01") ?? "";

                RecipeNameContent_02 = ConfigHelper.GetString("RecipeNameContent_02") ?? "";

                if (!string.IsNullOrEmpty(RecipeNameContent_01))
                {
                    LoadRecipeParameters(1, RecipeNameContent_01);
                }

                if (!string.IsNullOrEmpty(RecipeNameContent_02))
                {
                    LoadRecipeParameters(2, RecipeNameContent_02);
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), "[初始化参数异常]|初始化工作流程参数异常", ex, _currentUser?.UserAccount);
            }
        }

        /// <summary>
        /// 根据配方名称加载配方数据
        /// </summary>
        /// <param name="process">流程编号</param>
        /// <param name="recipeName">配方名称</param>
        private void LoadRecipeParameters(int process, string recipeName)
        {
            try
            {
                string selectSql = @"SELECT * FROM recipe_info WHERE recipe_name = @recipeName AND recipe_process = @recipeProcess";
                List<MySqlParameter> parameters = new List<MySqlParameter>();
                parameters.Add(new MySqlParameter("@recipeName", recipeName));
                parameters.Add(new MySqlParameter("@recipeProcess", process));

                var recipes = MysqlHelper.ExecuteQuery<RecipeModel>(selectSql,
                    (reader) =>
                    {
                        return new RecipeModel
                        {
                            RecipeId = Convert.ToInt32(reader["recipe_id"]),
                            RecipeName = reader["recipe_name"].ToString(),
                            RecipeProcess = Convert.ToInt32(reader["recipe_process"]),
                            CycleCount = Convert.ToInt32(reader["cycle_count"]),
                            DrawValue = reader["draw_value"].ToString(),
                            DrawKeepTime = Convert.ToInt32(reader["draw_keep_time"]),
                            PumpValue = reader["pump_value"].ToString(),
                            PumpKeepTime = Convert.ToInt32(reader["pump_keep_time"]),
                            VentValue = reader["vent_value"].ToString(),
                            StablePressureValue = reader["stable_pressure_value"].ToString(),
                            StablePressureKeepTime = Convert.ToInt32(reader["stable_pressure_keep_time"]),
                            CreateTime = Convert.ToDateTime(reader["create_time"]),
                            UpdateTime = Convert.ToDateTime(reader["update_time"]),
                            RecipeRemark = reader["recipe_remark"].ToString()
                        };
                    },
                    parameters.ToArray());

                if (recipes.Count > 0)
                {
                    var recipe = recipes[0];
                    switch (process)
                    {
                        case 1:
                            CycleCount_01 = recipe.CycleCount;
                            VacuumValue_01 = string.IsNullOrEmpty(recipe.DrawValue) ? 0 : Convert.ToDouble(recipe.DrawValue);
                            VacuumHoldTime_01 = recipe.DrawKeepTime;
                            HeliumValue_01 = string.IsNullOrEmpty(recipe.PumpValue) ? 0 : Convert.ToDouble(recipe.PumpValue);
                            HeliumHoldTime_01 = recipe.PumpKeepTime;
                            FinalHeliumValue_01 = string.IsNullOrEmpty(recipe.StablePressureValue) ? 0 : Convert.ToDouble(recipe.StablePressureValue);
                            FinalHoldTime_01 = recipe.StablePressureKeepTime;
                            RecipeNameContent_01 = recipe.RecipeName;
                            break;
                        case 2:
                            CycleCount_02 = recipe.CycleCount;
                            VacuumValue_02 = string.IsNullOrEmpty(recipe.DrawValue) ? 0 : Convert.ToDouble(recipe.DrawValue);
                            VacuumHoldTime_02 = recipe.DrawKeepTime;
                            HeliumValue_02 = string.IsNullOrEmpty(recipe.PumpValue) ? 0 : Convert.ToDouble(recipe.PumpValue);
                            HeliumHoldTime_02 = recipe.PumpKeepTime;
                            FinalHeliumValue_02 = string.IsNullOrEmpty(recipe.StablePressureValue) ? 0 : Convert.ToDouble(recipe.StablePressureValue);
                            FinalHoldTime_02 = recipe.StablePressureKeepTime;
                            RecipeNameContent_02 = recipe.RecipeName;
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), $"[加载配方数据异常]|加载流程{process}的配方{recipeName}数据异常", ex, _currentUser?.UserAccount);
            }
        }
        #endregion

        #region 漏率检测
        private CancellationTokenSource _leakageCts;

        private async void DeviceLeakageTestExecute(object obj)
        {
            if (!IsDeviceLeakageTesting)
            {
                // 开始设备漏率自检
                try
                {
                    _leakageCts = new CancellationTokenSource();
                    var cancellationToken = _leakageCts.Token;

                    DeviceLeakageTestContent = "停止检测";
                    IsDeviceLeakageTesting = true;

                    // 设备漏率检测流程：
                    // 1. 充压到3.5MPa
                    MessageBox.Show("开始设备漏率检测，正在充压到3.5MPa...", "提示", MessageBoxButton.OK, MessageBoxImage.Information);

                    // 模拟充压过程
                    for (int i = 0; i <= 100; i++)
                    {
                        if (cancellationToken.IsCancellationRequested)
                            throw new OperationCanceledException();

                        // 模拟充压到3.5MPa
                        double pressure = 3.5 * (i / 100.0);
                        DeviceLeakageRate = pressure.ToString("F2");
                        await Task.Delay(50, cancellationToken);
                    }

                    // 2. 关闭充气阀门
                    MessageBox.Show("充压完成，关闭充气阀门，开始10分钟稳压检测...", "提示", MessageBoxButton.OK, MessageBoxImage.Information);

                    // 3. 等待10分钟并记录压力变化
                    DateTime startTime = DateTime.Now;
                    double initialPressure = 3.5;
                    double currentPressure = initialPressure;

                    // 模拟压力缓慢下降（实际应用中应该从传感器读取）
                    for (int minute = 0; minute < 10; minute++)
                    {
                        for (int second = 0; second < 60; second++)
                        {
                            if (cancellationToken.IsCancellationRequested)
                                throw new OperationCanceledException();

                            // 模拟压力缓慢下降
                            currentPressure = initialPressure - (minute * 60 + second) * 0.0001;
                            DeviceLeakageRate = currentPressure.ToString("F3");

                            // 显示倒计时
                            int remainingSeconds = (10 * 60) - (minute * 60 + second);
                            DeviceLeakageTestContent = $"检测中 {remainingSeconds / 60:D2}:{remainingSeconds % 60:D2}";

                            await Task.Delay(1000, cancellationToken);
                        }
                    }

                    // 4. 计算漏率
                    double finalPressure = currentPressure;
                    double pressureDrop = initialPressure - finalPressure;
                    // 简化计算：漏率 = 压力降 / 时间
                    double leakageRate = pressureDrop / 10.0; // 10分钟

                    DeviceLeakageRate = leakageRate.ToString("F6");
                    MessageBox.Show($"设备漏率检测完成！\n初始压力: {initialPressure:F2}MPa\n最终压力: {finalPressure:F4}MPa\n压力降: {pressureDrop:F6}MPa\n漏率: {leakageRate:F6}MPa/min",
                                  "检测完成", MessageBoxButton.OK, MessageBoxImage.Information);
                }
                catch (OperationCanceledException)
                {
                    // 用户取消操作
                    MessageBox.Show("设备漏率检测已取消", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"设备漏率自检出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                }
                finally
                {
                    DeviceLeakageTestContent = "设备漏率自检";
                    IsDeviceLeakageTesting = false;
                    _leakageCts?.Dispose();
                    _leakageCts = null;
                }
            }
            else
            {
                // 停止设备漏率自检
                var result = MessageBox.Show("是否停止设备漏率自检?", "确认停止", MessageBoxButton.YesNo, MessageBoxImage.Question);
                if (result == MessageBoxResult.Yes)
                {
                    _leakageCts?.Cancel();
                }
            }
        }

        private async void ProductLeakageTestExecute(object obj)
        {
            if (!IsProductLeakageTesting)
            {
                // 开始产品漏率检测
                try
                {
                    _leakageCts = new CancellationTokenSource();
                    var cancellationToken = _leakageCts.Token;

                    ProductLeakageTestContent = "停止检测";
                    IsProductLeakageTesting = true;

                    // 产品漏率检测流程：
                    // 1. 充压到1.0MPa
                    MessageBox.Show("开始产品漏率检测，正在充压到1.0MPa...", "提示", MessageBoxButton.OK, MessageBoxImage.Information);

                    // 模拟充压过程
                    for (int i = 0; i <= 100; i++)
                    {
                        if (cancellationToken.IsCancellationRequested)
                            throw new OperationCanceledException();

                        // 模拟充压到1.0MPa
                        double pressure = 1.0 * (i / 100.0);
                        ProductLeakageRate = pressure.ToString("F2");
                        await Task.Delay(20, cancellationToken);
                    }

                    // 2. 保持1分钟并记录压力变化
                    MessageBox.Show("充压完成，开始1分钟稳压检测...", "提示", MessageBoxButton.OK, MessageBoxImage.Information);

                    DateTime startTime = DateTime.Now;
                    double initialPressure = 1.0;
                    double currentPressure = initialPressure;

                    // 等待1分钟并监控压力变化
                    for (int second = 0; second < 60; second++)
                    {
                        if (cancellationToken.IsCancellationRequested)
                            throw new OperationCanceledException();

                        // 模拟压力变化
                        currentPressure = initialPressure - second * 0.001;
                        ProductLeakageRate = currentPressure.ToString("F3");

                        // 显示倒计时
                        int remainingSeconds = 60 - second;
                        ProductLeakageTestContent = $"检测中 00:{remainingSeconds:D2}";

                        await Task.Delay(1000, cancellationToken);
                    }

                    // 3. 计算漏率
                    double finalPressure = currentPressure;
                    double pressureDrop = initialPressure - finalPressure;
                    // 简化计算：漏率 = 压力降 / 时间
                    double leakageRate = pressureDrop / 1.0; // 1分钟

                    ProductLeakageRate = leakageRate.ToString("F4");
                    MessageBox.Show($"产品漏率检测完成！\n初始压力: {initialPressure:F2}MPa\n最终压力: {finalPressure:F3}MPa\n压力降: {pressureDrop:F4}MPa\n漏率: {leakageRate:F4}MPa/min",
                                  "检测完成", MessageBoxButton.OK, MessageBoxImage.Information);
                }
                catch (OperationCanceledException)
                {
                    // 用户取消操作
                    MessageBox.Show("产品漏率检测已取消", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"产品漏率检测出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                }
                finally
                {
                    ProductLeakageTestContent = "产品漏率检测";
                    IsProductLeakageTesting = false;
                    _leakageCts?.Dispose();
                    _leakageCts = null;
                }
            }
            else
            {
                // 停止产品漏率检测
                var result = MessageBox.Show("是否停止产品漏率检测?", "确认停止", MessageBoxButton.YesNo, MessageBoxImage.Question);
                if (result == MessageBoxResult.Yes)
                {
                    _leakageCts?.Cancel();
                }
            }
        }
        #endregion

        #endregion

        #region 更新当前登录用户的信息 事件处理
        /// <summary>
        /// 接收到通知
        /// </summary>
        private void OnUserInfoUpdate(object sender, UserInfoUpdateEventArgs e)
        {
            // 空值检查，避免NullReferenceException
            if (e?.UpdatedUser != null)
            {
                _currentUser = e.UpdatedUser;
                Debug.WriteLine("Home页面|用户信息已更新");
            }
            else
            {
                Debug.WriteLine("收到空的事件参数");
            }
        }

        /// <summary>
        /// 析构函数中的事件取消订阅
        /// </summary>
        ~HomeViewModel()
        {
            _shellViewModel.UserInfoUpdate -= OnUserInfoUpdate;

            // 正确释放CancellationTokenSource
            if (_cts != null)
            {
                _cts.Cancel();
                _cts.Dispose();
                _cts = null;
            }
        }
        #endregion

        #region 更新管道动画 10/30 待完善
        /// <summary>
        /// 更新设备状态
        /// </summary>
        /// <param name="status">0 停止状态 1 抽真空状态 2 充氦气状态 3 排气状态</param>
        /// <param name="devNum"></param>
        private void UpdateDeviceAnimation(int status)
        {
            // 根据设备状态进行更新
            DeviceDataStore.DEV_STATUS = status;
        }
        #endregion


    }
}
